package com.dwxt.cdms.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dwxt.cdms.constant.EquipCategory;
import com.dwxt.cdms.dao.CustomerMapper;
import com.dwxt.cdms.dao.EquipmentCustomMapper;
import com.dwxt.cdms.dao.EquipmentMapper;
import com.dwxt.cdms.entity.Customer;
import com.dwxt.cdms.entity.Equipment;
import com.dwxt.cdms.entity.EquipmentCustom;
import com.dwxt.cdms.exception.CustomException;
import com.dwxt.cdms.view.EquipmentCustomView;
import com.dwxt.cdms.vo.SelectEquipmentCustomVo;
import com.dwxt.common.base.BaseResult;
import com.dwxt.common.base.StatusCode;
import com.dwxt.common.constant.VariableConstants;
import com.dwxt.common.util.SnowIdUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 设备&客户 关联
 *
 * @author Kuang.JiaZhuo
 * @date 2020-09-05 16:27
 */
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Slf4j
public class EquipmentCustomService {

    private final EquipmentCustomMapper equipmentCustomMapper;
    private final EquipmentMapper equipmentMapper;
    private final StationService stationService;
    private final LbWatchService lbWatchService;
    private final CustomerMapper customerMapper;

    @Autowired
    private YouthHopeService youthHopeService;

    @Value("${witheart.deptid}")
    private String deptid;

    /**
     * @方法名：bindEquipment
     * @描述： 绑定设备
     * @作者： kjz
     * @日期： Created in 2020/9/5 16:31
     */
    @Transactional(rollbackFor = Exception.class)
    public int bindEquipment(EquipmentCustom equipmentCustom) throws IOException {
        Integer customerId = equipmentCustom.getCustomerId();

        if (null == customerId || "".equals(customerId)) {
            throw new CustomException(StatusCode.CUSTOMER_ID_NOT_NULL);
        }

        String equipmentId = equipmentCustom.getEquipmentId();
        if (null == equipmentId || "".equals(equipmentId)) {
            throw new CustomException(StatusCode.EQUIPMENT_ID_NOT_NULL);
        }

        if (judgeBindReDo(equipmentCustom)) {
            throw new CustomException(StatusCode.YES_BIND_EQUIPMENT);
        }
        Equipment equipment = equipmentMapper.selectByPrimaryKey(equipmentId);
        String paramCategory = equipment.getCategory();
        //判断血糖仪和poct设备是否重复
        SelectEquipmentCustomVo selectVo = new SelectEquipmentCustomVo();
        selectVo.setCustomerId(customerId);
        List<EquipmentCustomView> list = equipmentCustomMapper.selectEquipmentCustomList(selectVo);
        if (list != null && list.size() > 0) {
            boolean repeat = list.stream().anyMatch(equipmentCustomView -> equipmentCustomView.getCategory().equals(paramCategory));
            if (repeat) {
                throw new CustomException(StatusCode.YES_BIND_EQUIPMENT_TYPE);
            }
        }


        if (equipment != null && equipment.getType().equals(VariableConstants.STRING_CONSTANT_1)) {
            throw new CustomException(StatusCode.YES_BIND_EQUIPMENT);
        }
        List<Equipment> equipmentList = selectEquipmentByCustomerId(customerId);
        //boolean isAble = judgeBindEquipment(equipmentList, equipment);
        if (!judgeBindEquipment(equipmentList, equipment)) {
            throw new CustomException(StatusCode.YES_BIND_EQUIPMENT_TYPE);
        }
        equipmentCustom.setId(SnowIdUtil.getInstance().nextId())
                .setCreateTime(LocalDateTime.now())
                .setIsDelete(VariableConstants.STRING_CONSTANT_0);

        //设备为睡眠仪时在心晓服务器创建用户并绑定设备
        if (EquipCategory.SMY.equals(equipment.getCategory())) {
            //创建用户
            HashMap<String, Object> userMap = new HashMap<>();
            userMap.put("deptid", deptid);
            userMap.put("mobile", equipmentCustom.getMobile());
            userMap.put("nick", equipmentCustom.getMobile());
            userMap.put("headimgurl", "");
            userMap.put("birthday", equipmentCustom.getBirthday());
            userMap.put("Perplex", equipmentCustom.getPerplex());
            userMap.put("Medicine", equipmentCustom.getMedicine());
            JSONObject addUserResult = youthHopeService.getWitheartData(userMap, "/lite/Admin/UserCreate");
            if (addUserResult.get("code").equals(0)) {
                JSONObject user = (JSONObject) addUserResult.get("data");
                String userid = (String) user.get("userid");
                //设备绑定
                HashMap<String, String> param = new HashMap<>();
                param.put("deptid", deptid);
                param.put("sn", equipment.getSerialNumber());
                param.put("userid", userid);
                JSONObject bindUserResult = youthHopeService.getWitheartData(param, "/lite/Admin/Boxbind");
                String result = (String) bindUserResult.get("data");
                result = result.replaceAll("\"", "");
                if (!"1".equals(result)) {
                    log.error("心晓睡眠仪绑定失败，失败原因：【" + result + "】 (0没有关注公众号 1 为绑定成功，2绑定失败，3此设备不存在,4为用户不存在,5此设备已经被绑定,6此设备已经被冻结,7您已经绑定设备)");
                }
                equipmentCustom.setWitheartUserid(userid);
            } else {
                log.error("心晓睡眠仪创建用户失败，失败信息：" + equipmentCustom.toString());
                return 0;
            }

        }
        //设备为胸卡时下发亲人电话号码
        if (EquipCategory.XK.equals(equipment.getCategory())) {
            sendXkData(equipment.getSerialNumber(), equipmentCustom.getXkParams());
        }
        //设备为来邦手表时，修改来邦手表姓名电话
        if (EquipCategory.LB.equals(equipment.getCategory())) {
            Customer customer = customerMapper.selectByPrimaryKey(equipmentCustom.getCustomerId());
            lbWatchService.updateElder(equipment.getLbUserid(), customer);
        }
        this.equipmentMapper.updateDistributionStatusToOne(equipmentId);
        return equipmentCustomMapper.insert(equipmentCustom);
    }

    //胸卡下发亲人电话号码
    private void sendXkData(String serialNumber, String xkParams) throws IOException {
        HashMap<String, Object> map = new HashMap<>();
        map.put("CmdCode", "NB0B");
        map.put("IMEI", serialNumber);
        map.put("Params", xkParams);
        OkHttpClient client = new OkHttpClient();
        MediaType mediaType = MediaType.parse("application/json");
        RequestBody body = RequestBody.create(mediaType, JSON.toJSONString(map));
        Request request = new Request.Builder()
                .url("http://www.aiday.com.cn:10502/api/Command/SendNbCommand")
                .post(body)
                .addHeader("Content-Type", "application/json")
                .addHeader("Cache-Control", "no-cache")
                .build();
        Response response = client.newCall(request).execute();
        String res = response.body().string();
        JSONObject jsonObject = JSON.parseObject(res);
        Object state = jsonObject.get("State");
        if (state == null || !state.equals(0)) {
            log.error("胸卡下发亲人电话号码失败。失败序列号：" + serialNumber + ",参数：" + xkParams);
        }
    }

    public boolean judgeBindEquipment(List<Equipment> equipmentList, Equipment equipment) {
        List<String> collect = equipmentList.stream().map(Equipment::getCategory).collect(Collectors.toList());
        List<String> list = Arrays.asList(EquipCategory.ZNSB, EquipCategory.ZNSH);
        List<String> poctList = Arrays.asList(EquipCategory.POCT4, EquipCategory.POCT7);
        if (collect.contains(equipment.getCategory())) {
            return false;
        } else if (list.contains(equipment.getCategory()) && (collect.contains(EquipCategory.ZNSB) || collect.contains(EquipCategory.ZNSH))) {
            return false;
        } else if (poctList.contains(equipment.getCategory()) && (collect.contains(EquipCategory.POCT4) || collect.contains(EquipCategory.POCT7))) {
            return false;
        }
        return true;
    }

    public List<Equipment> selectEquipmentByCustomerId(Integer customerId) {
        List<Equipment> equipmentList = new ArrayList<>();
        List<EquipmentCustom> equipmentCustomList = selectByCustomerId(customerId);
        List<String> list = equipmentCustomList.stream().map(EquipmentCustom::getEquipmentId).collect(Collectors.toList());
        if (list.size() > 0) {
            Example example = new Example(Equipment.class);
            example.createCriteria().andIn("id", list);
            equipmentList = equipmentMapper.selectByExample(example);
        }
        return equipmentList;
    }


    /**
     * @方法名：judgeBindReDo
     * @描述： 判断绑定是否重复
     * @作者： kjz
     * @日期： Created in 2020/9/25 16:10
     */
    public boolean judgeBindReDo(EquipmentCustom equipmentCustom) {
        int count = equipmentCustomMapper.selectEquipmentCustomCount(equipmentCustom);
        return count == 0 ? false : true;
    }

    /**
     * @方法名：selectEquipmentCustomById
     * @描述： 根据id查询【设备&客户】详情
     * @作者： kjz
     * @日期： Created in 2020/9/5 16:45
     */
    public EquipmentCustomView selectEquipmentCustomById(String id) {
        EquipmentCustomView equipmentCustomView = equipmentCustomMapper.selectEquipmentCustomById(id);
        return equipmentCustomView;
    }

    /**
     * @方法名：selectEquipmentCustomList
     * @描述： 按条件查询【设备&客户】列表(带分页)
     * @作者： kjz
     * @日期： Created in 2020/9/5 17:45
     */
    public PageInfo<EquipmentCustomView> selectEquipmentCustomList(SelectEquipmentCustomVo selectVo) {
        Integer stationId = null;
        try {
            stationId = stationService.getLoginUserStation();
        } catch (Exception e) {//小程序登录
        }
        PageHelper.startPage(selectVo.getPageNum(), selectVo.getPageSize());
        if (stationId != null) {
            selectVo.setStationId(stationId);
        }
        List<EquipmentCustomView> adminUserVos = equipmentCustomMapper.selectEquipmentCustomList(selectVo);
        PageInfo<EquipmentCustomView> pageInfo = new PageInfo(adminUserVos);
        return pageInfo;
    }

    /**
     * @方法名：deleteDataByIds
     * @描述： 批量删除【设备&客户】
     * @作者： kjz
     * @日期： Created in 2020/9/5 17:52
     */
    @Transactional(rollbackFor = Exception.class)
    public int deleteDataByIds(String[] ids) throws IOException {
        if (null == ids || ids.length == 0) {
            throw new CustomException(StatusCode.ID_IS_NULL);
        }
        for (String id : ids) {
            EquipmentCustom equipmentCustom = equipmentCustomMapper.selectByPrimaryKey(id);
            Equipment equipment = this.equipmentMapper.selectEquipmentById(equipmentCustom.getEquipmentId());
            //当设备为心晓睡眠仪解绑心晓设备
            if (EquipCategory.SMY.equals(equipment.getCategory())) {
                HashMap<String, Object> map = new HashMap<>();
                map.put("deptid", deptid);
                map.put("sn", equipment.getSerialNumber());
                map.put("userid", equipmentCustom.getWitheartUserid());
                JSONObject jsonObject = youthHopeService.getWitheartData(map, "/lite/Admin/BoxUnbind");
                String unBindResult = (String) jsonObject.get("data");
                unBindResult = unBindResult.replaceAll("\"", "");
                if (!"1".equals(unBindResult)) {
                    log.error("心晓睡眠仪解绑失败，失败信息：" + equipmentCustom.toString());
                }
            }
        }
        //解除设备绑定，改变设备的发放状态
        this.equipmentCustomMapper.updateDistributionStatusToZeroByEquipmentCustomIds(ids);

        int result = equipmentCustomMapper.deleteEquipmentCustomByIds(ids);
        //删除其他关联

        return result;
    }

    /**
     * 根据customerId查询数据
     *
     * @param Id
     * @return
     */
    public List<EquipmentCustom> selectByCustomerId(Integer Id) {
        return equipmentCustomMapper.selectByCustomerId(Id);
    }


    /**
     * @方法名：selectEquipmentCustomByDeviceIdentity
     * @描述： 根据设备标识查询【设备&客户】数据
     * @作者： kjz
     * @日期： Created in 2020/9/10 16:34
     */
    public EquipmentCustom selectEquipmentCustomByDeviceIdentity(String deviceIdentity) {
        EquipmentCustom equipmentCustom = equipmentCustomMapper.selectEquipmentCustomByDeviceIdentity(deviceIdentity);
        return equipmentCustom;
    }

    /**
     * @方法名：unbindEquipment
     * @描述： 解除绑定
     * @作者： kjz
     * @日期： Created in 2020/9/11 19:14
     */
    @Transactional(rollbackFor = Exception.class)
    public int unbindEquipment(String equipmentId) {
        this.equipmentMapper.updateDistributionStatusToZero(equipmentId);
        return equipmentCustomMapper.deleteEquipmentCustomByEquipmentId(equipmentId);
    }

    /**
     * 批量删除发放设备信息 并修改设备绑定状态
     *
     * @param ids
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public int deleteDataByCustomerIds(Integer[] ids) {
        if (null == ids || ids.length == 0) {
            throw new CustomException(StatusCode.ID_IS_NULL);
        }
        //解除设备绑定，改变设备的发放状态
        this.equipmentCustomMapper.updateDistributionStatusToZeroByCustomIds(ids);
        int result = equipmentCustomMapper.deleteEquipmentCustomByCustomerIds(ids);
        //删除其他关联

        return result;
    }

    public void insert(EquipmentCustom equipmentCustom) {
        equipmentCustomMapper.insert(equipmentCustom);
    }

    public BaseResult selectEquipmenctType(Integer customerId) {
        HashMap<String, Object> map = new HashMap<>();
        List<Equipment> list = this.selectEquipmentByCustomerId(customerId);
        //poct4
        if (list.stream().anyMatch(equipment -> equipment.getCategory().equals("6"))) {
            map.put("poct4", true);
        } else {
            map.put("poct4", false);
        }
        //poct8
        if (list.stream().anyMatch(equipment -> equipment.getCategory().equals("7"))) {
            map.put("poct8", true);
        } else {
            map.put("poct8", false);
        }
        return BaseResult.ok(map);
    }

    public BaseResult selectEquipmentListByCustomerId(Integer customerId) {
        List<Equipment> equipmentList = equipmentMapper.selectEquipmentListByCustomerId(customerId);
        return BaseResult.ok(equipmentList);
    }

    public BaseResult selectCustomerBySerialNumber(String serialNumber) {
        Customer customer = equipmentCustomMapper.selectCustomerBySerialNumber(serialNumber);
        return BaseResult.ok(customer);
    }


    public String selectLbUseridByCustomerId(Integer customerId) {
        return equipmentCustomMapper.selectLbUseridByCustomerId(customerId);
    }
}
